package btb.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;

import de.matthiasmann.twl.GUI;
import de.matthiasmann.twl.Rect;
import de.matthiasmann.twl.ResizableFrame;
import de.matthiasmann.twl.ScrollPane;
import de.matthiasmann.twl.TextArea;
import de.matthiasmann.twl.Timer;
import de.matthiasmann.twl.ValueAdjusterInt;
import de.matthiasmann.twl.model.SimpleIntegerModel;
import de.matthiasmann.twl.textarea.HTMLTextAreaModel;
import de.matthiasmann.twl.textarea.StyleAttribute;
import de.matthiasmann.twl.textarea.StyleSheet;
import de.matthiasmann.twl.textarea.TextAreaModel;
import de.matthiasmann.twl.textarea.Value;
import de.matthiasmann.twl.utils.TextUtil;

public final class CGuiUtils
{
	private CGuiUtils(){}
	
	public static void println( String str )
	{
		System.out.println( str );
	}
	
	//@SuppressWarnings( "CallToThreadDumpStack" )
	public static void errMsg( Throwable ex )
	{
		println( "Well ain't this a bitch?" );
		
		ex.printStackTrace();
		
		StringWriter strWrit = new StringWriter();
		PrintWriter printWrit = new PrintWriter( strWrit );
		
		ex.printStackTrace( printWrit );
		
		printWrit.flush();
		Sys.alert( "Error!", strWrit.toString() );
	}
	
	public static void reduceInputLag()
	{
		GL11.glGetError(); 			// This call will burn the time between vsyncs, apparently.
		Display.processMessages(); 	// Process new native messages since Display.update().
		Mouse.poll(); 				// Update Mouse events,
		Keyboard.poll(); 			// and Keyboard events as well.
	}
	
	static class TextFrame extends ResizableFrame
	{
        private final HTMLTextAreaModel textAreaModel;
        private final TextArea textArea;
        private final ScrollPane scrollPane;
        private Timer timer;
        private int size;
        private int dir;

        private static final int MIN_SIZE = 128;
        private static final int MAX_SIZE = 256;

        public TextFrame( String str, int option )
        {
            setTitle( "Text" );

            this.textAreaModel = new HTMLTextAreaModel();
            this.textArea = new TextArea( textAreaModel );

            switch( option )
            {
            case 1: readFile( str );
            	break;
            case 2: setHTML( str );           	
            	break;
            default:
            	break;
            }

            textArea.addCallback( new TextArea.Callback()
            {
                public void handleLinkClicked( String href )
                {
                    if( href.startsWith ("javascript:" ) )
                    {
                        handleAction( href.substring( 11 ) );
                    }
                    else if( href.startsWith( "#" ) )
                    {
                        TextAreaModel.Element ankor = textAreaModel.getElementById (href.substring( 1 ) );
                        if( ankor != null )
                        {
                            Rect rect = textArea.getElementRect( ankor );
                            if( rect != null )
                            {
                                scrollPane.setScrollPositionY( rect.getY() );
                            }
                        }
                    }
                    else
                    {
                        readFile( href );
                    }
                }
            } );

            ValueAdjusterInt vai = new ValueAdjusterInt( new SimpleIntegerModel( 0, 100, 50 ) );
            vai.setTooltipContent( "Select a nice value" );
            textArea.registerWidget( "niceValueSlider", vai );
            
            scrollPane = new ScrollPane( textArea );
            scrollPane.setFixed( ScrollPane.Fixed.HORIZONTAL );

            add( scrollPane );
        }

        @Override
        protected void afterAddToGUI( GUI gui )
        {
            super.afterAddToGUI( gui );
            timer = gui.createTimer();
            timer.setDelay( 16 );
            timer.setContinuous( true );
            timer.setCallback( new Runnable()
            {
                public void run()
                {
                    animate();
                }
            } );
        }

        @Override
        protected void beforeRemoveFromGUI( GUI gui )
        {
            super.beforeRemoveFromGUI( gui );
            timer.stop();
            timer = null;
        }

        void setHTML( String new_html )
        {
        	textAreaModel.setHtml( new_html );
        	setTitle( TextUtil.notNull( textAreaModel.getTitle() ) );
        }
        
        void readFile( String filename )
        {
            try
            {
                textAreaModel.readHTMLFromURL( CGuiUtils.class.getResource( filename ) );

                StyleSheet styleSheet = new StyleSheet();
                for( String styleSheetLink : textAreaModel.getStyleSheetLinks() )
                {
                    try
                    {
                        styleSheet.parse( CGuiUtils.class.getResource( styleSheetLink ) );
                    }
                    catch( IOException ex )
                    {
                        Logger.getLogger( CGuiUtils.class.getName() ).log( Level.SEVERE,
                                "Can't parse style sheet: " + styleSheetLink, ex );
                    }
                }
                textArea.setStyleClassResolver( styleSheet );
                
                setTitle( TextUtil.notNull( textAreaModel.getTitle() ) );

                size = MIN_SIZE;
                dir = -4;
            }
            catch( IOException ex )
            {
                Logger.getLogger( CGuiUtils.class.getName() ).log( Level.SEVERE, "Can't read HTML: " + filename, ex );
            }
        }

        void handleAction( String what )
        {
            if( "zoomImage()".equals( what ) )
            {
                if( timer != null && !timer.isRunning() )
                {
                    dir = -dir;
                    timer.start();
                }
            }
        }

        void animate()
        {
            size = Math.max( MIN_SIZE, Math.min( MAX_SIZE, size + dir ) );
            if( size == MIN_SIZE || size == MAX_SIZE )
            {
                timer.stop();
            }

            TextAreaModel.Element e = textAreaModel.getElementById( "portrait" );
            if( e != null )
            {
                e.setStyle( e.getStyle().with( StyleAttribute.WIDTH, new Value( size, Value.Unit.PX ) ) );
                textAreaModel.domModified();
            }
        }
    }
	
	public static void main( String[] args )
	{
		// TODO Auto-generated method stub
	}
}
